home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / csv / convert.pas < prev    next >
Pascal/Delphi Source File  |  1995-12-22  |  9KB  |  317 lines

  1. unit Convert;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, StdCtrls, DBTables, DB, Grids, DBGrids;
  8.  
  9. Const
  10.   Delimiter = '"';
  11.   Separator = ',';
  12.   Special   = '';{Alt 127}
  13.   MaxField = 128; {Each line is 256 bytes in length and a comma after each value}
  14.   FieldTypeStr : Array[TFieldType] of String[15] = 
  15.     ('ftUnknown','ftString','ftSmallint','ftInteger','ftWord',
  16.      'ftBoolean',' ftFloat','ftCurrency','ftBCD','ftDate','ftTime',
  17.      'ftDateTime','ftBytes','ftVarBytes','ftBlob','ftMemo','ftGraphic');
  18.  
  19. Type
  20.   FieldsType = record
  21.     Count    : Byte;
  22.     Field    : Array[1..MaxField] of record
  23.       FieldIs  : TFieldType;
  24.       FieldLen : Byte;
  25.     end;
  26.   end;
  27.  
  28. type
  29.   TForm1 = class(TForm)
  30.     Table1: TTable;
  31.     Table2: TTable;
  32.     BatchMove1: TBatchMove;
  33.     OpenDialog1: TOpenDialog;
  34.     Button1: TButton;
  35.     Edit1: TEdit;
  36.     Label1: TLabel;
  37.     ListBox1: TListBox;
  38.     Edit2: TEdit;
  39.     Label2: TLabel;
  40.     procedure Button1Click(Sender: TObject);
  41.   private
  42.     { Private declarations }
  43.     Procedure FieldSizeAndTypeOf(Line : String; Nth : Byte; var Field : TFieldType; var Size : Byte);
  44.     Procedure FindFieldTypes(Filename : String; var Fields : FieldsType);
  45.     Procedure DefineFields(var Table2 : TTable; Filename : String);
  46.   public
  47.     { Public declarations }
  48.   end;
  49.  
  50. var
  51.   Form1: TForm1;
  52.  
  53. implementation
  54.  
  55. {$R *.DFM}
  56.  
  57. Type
  58.   MyException = class(Exception);
  59.  
  60. Function Word2Str(W : Word) : String;
  61. var
  62.   S : String;
  63. begin
  64.   Str(W,S);
  65.   Word2Str := S;
  66. end;
  67.  
  68. Procedure PreProcess(var S : String);
  69. var
  70.   InText : Boolean;
  71.   C      : Byte;
  72. begin
  73.   {Convert any separators within delimitors into a special character}
  74.   {i.e. "Hello world, How are you", becomes
  75.         "Hello world How are you"}
  76.   C := Pos(Delimiter,S);
  77.   if C<>0 then begin
  78.     {Don't bother trying to any conversion if there are no delimitors!}
  79.     InText := False;
  80.     for C := 1 to Length(S) do begin
  81.       if S[C]=Delimiter then
  82.         InText:=not InText;
  83.       if (S[C]=Separator) and InText then
  84.         S[C] := Special;
  85.     end;
  86.   end;
  87. end;
  88.  
  89. Function CountSeparators(S : String) : Word;
  90. var
  91.   P,C    : Byte;
  92. begin
  93.   C := 1;
  94.   P := Pos(Separator,S);
  95.   while P<>0 do begin
  96.     Inc(C);
  97.     S[P] := ' ';
  98.     P := Pos(Separator,S);
  99.   end;
  100.   CountSeparators := C;
  101. end;
  102.  
  103. Function  NthItem(N : Byte; S : String) : String;
  104. var
  105.   P,C : Byte;
  106. begin
  107.   C := 1;
  108.   P := Pos(',',S);
  109.   while (C<>N) do begin
  110.     Inc(C);
  111.     Delete(S,1,P);
  112.     P := Pos(Separator,S);
  113.   end;
  114.   if P>0 then
  115.     Delete(S,P,Length(S)-P+1); {Chop the end off the string}
  116.   {Remove any delimiters from around the string}
  117.   if S[1]=Delimiter then
  118.     Delete(S,1,1);
  119.   if S[Length(S)]=Delimiter then
  120.     Delete(S,Length(S),1);
  121.  
  122.   {Convert any specials back to separators}
  123.   P := Pos(Special, S);
  124.   while P<>0 do begin
  125.     S[P] := Separator;
  126.     P := Pos(Special, S);
  127.   end;
  128.   NthItem := S;
  129. end;
  130.  
  131. Procedure TForm1.FieldSizeAndTypeOf(Line : String; Nth : Byte; var Field : TFieldType; var Size : Byte);
  132. var
  133.   P,C : Byte;
  134.   Numbs,
  135.   Letts : Boolean;
  136.   Punct : String;
  137. begin
  138.   Line := NthItem(Nth, Line);
  139.  
  140.   Field := ftUnknown;
  141.   Size := 0;
  142.   {Determine field type}
  143.   if Length(Line)>1 then begin
  144.     Numbs := False;
  145.     Letts := False;
  146.     Punct := '';
  147.     for C := 1 to Length(Line) do begin
  148.       if not Letts and (Line[C] in ['A'..'Z',' ','a'..'z']) then
  149.         Letts := True;
  150.       if not Numbs and (Line[C] in ['0'..'9']) then
  151.         Numbs := True;
  152.       if not (Line[C] in ['A'..'Z',' ','a'..'z','0'..'9']) then
  153.         if Pos(Line[C],Punct)=0 then
  154.           Punct := Punct + Line[C];
  155.     end;
  156.     if Numbs and not Letts then begin
  157.       if Punct='' then begin
  158.         {Its a number}
  159.         Field := ftInteger;
  160.       end else begin
  161.         {Its numbers and punctuation so could be date,time or real}
  162.         if Length(Punct)=1 then begin
  163.           Case Punct[1] of
  164.             ':' : Field := ftTime;
  165.             '/' : Field := ftDate;
  166.             '.' : Field := ftFloat;
  167.           else
  168.             Field := ftString;
  169.           end;
  170.         end else
  171.           Field := ftString;
  172.       end;
  173.     end else
  174.       Field := ftString;
  175.     Case Field of
  176.       ftString : Size := Length(Line);
  177.     end;
  178.   end;
  179. end;
  180.  
  181. Procedure TForm1.FindFieldTypes(Filename : String; var Fields : FieldsType);
  182. var
  183.   Fil    : TextFile;
  184.   Line   : String;
  185.   C      : Byte;
  186.   TmpIs  : TFieldType;
  187.   TmpLen : Byte;
  188. begin
  189.   FillChar(Fields, SizeOf(Fields), 0);
  190.  
  191.   try
  192.     AssignFile(Fil,Filename);
  193.     Reset(Fil);
  194.     with Fields do begin
  195.       Count := 0;
  196.       ListBox1.Clear;
  197.       repeat
  198.         Readln(Fil,Line);
  199.         Edit2.Text := Line;
  200.         Edit2.Refresh;
  201.         PreProcess(Line);
  202.         C := CountSeparators(Line);
  203.         if (C<>Count) then begin
  204.           if (Count<>0) then 
  205.             Raise MyException.Create('Inconsistant number of fields!');
  206.           Count := C;
  207.           Edit1.Text := Word2Str(C);
  208.           Edit1.Refresh;
  209.         end;
  210.  
  211.         for C := 1 to Count do with Field[C] do begin
  212.           FieldSizeAndTypeOf(Line,C,TmpIs,TmpLen);
  213.           if (TmpIs<>FieldIs) then begin
  214.             if FieldIs=ftUnknown then begin
  215.               ListBox1.Items.Add(Word2Str(C)+' '+FieldTypeStr[TmpIs]+' '+Word2Str(TmpLen));
  216.               ListBox1.Refresh;
  217.             end else if TmpIs<>ftUnknown then
  218.               Raise MyException.Create('Field '+Chr(C+Ord('0'))+' has changed type!');
  219.           end;
  220.           if TmpIs<>ftUnknown then begin
  221.             FieldIs := TmpIs;
  222.             if TmpLen>FieldLen then begin
  223.               ListBox1.Items.Add(Word2Str(C)+' '+FieldTypeStr[FieldIs]+' '+Word2Str(TmpLen));
  224.               ListBox1.Items.Exchange(C-1,ListBox1.Items.Count-1);
  225.               ListBox1.Items.Delete(ListBox1.Items.Count-1);
  226.               ListBox1.Refresh;
  227.               FieldLen := TmpLen;
  228.             end;
  229.           end; 
  230.         end;
  231.       until Eof(Fil);
  232.       for C := 1 to Count do with Field[C] do begin
  233.         {Any fields we cannot understand are strings!}
  234.         if FieldIs=ftUnknown then
  235.           FieldIs := ftString;
  236.         {Any String fields with no length have to be at least 1 in length!}
  237.         if (FieldLen=0) and (FieldIs=ftString) then
  238.           FieldLen := 1;
  239.       end;
  240.     end;
  241.   finally
  242.     CloseFile(Fil);
  243.   end;
  244. end;
  245.  
  246. Procedure TForm1.DefineFields(var Table2 : TTable; Filename : String);
  247. var
  248.   Fields : FieldsType;
  249.   Fil    : TextFile;
  250.   C      : Byte;
  251. begin
  252.   FindFieldTypes(Filename, Fields);
  253.  
  254.   with Table2 do begin
  255.     FieldDefs.Clear;
  256.     IndexDefs.Clear;
  257.   end;
  258.  
  259.   AssignFile(Fil,Copy(Filename,1,Pos('.',Filename)-1)+'.SCH');
  260.   ReWrite(Fil);
  261.   Writeln(Fil,'[',ExtractFilename(Copy(Filename,4,Pos('.',Filename)-4)),']');
  262.   Writeln(Fil,'Filetype=VARYING');
  263.   Writeln(Fil,'Delimiter="');
  264.   Writeln(Fil,'Separator=,');
  265.   Writeln(Fil,'CharSet=ascii');
  266.   with Fields do begin
  267.     for C := 1 to Count do with Field[C] do begin
  268.       Write(Fil,'Field',C,'=','Field',C,',');
  269.       Case FieldIs of
  270.         ftInteger : Writeln(Fil,'LONGINT,',FieldLen,',0,0');
  271.         ftFloat   : Writeln(Fil,'FLOAT,',FieldLen,',',(FieldLen-1 div 2)+1,',0');
  272.         ftDate    : Writeln(Fil,'DATE,',FieldLen,',0,0');
  273.         ftTime    : Writeln(Fil,'TIME,',FieldLen,',0,0');
  274.       else
  275.         Writeln(Fil,'CHAR,',FieldLen,',0,0');
  276.       end;
  277.       Table2.FieldDefs.Add('Field'+Word2Str(C), FieldIs, FieldLen, False);
  278.       if C=1 then
  279.         Table2.IndexDefs.Add('Field'+Word2Str(C)+'Index', 'Field'+Word2Str(C), [ixPrimary, ixUnique]);
  280.     end;
  281.   end;
  282.   System.Close(Fil);
  283.   Table2.CreateTable;
  284. end;
  285.  
  286. procedure TForm1.Button1Click(Sender: TObject);
  287. var
  288.   Define : Boolean;
  289.   DBFile : String;
  290.   Button : Integer;
  291.   P      : Byte;
  292. begin
  293.   if OpenDialog1.Execute then begin
  294.     Table1.Tablename := OpenDialog1.Filename;
  295.     P := Pos('.',OpenDialog1.Filename);
  296.     DBFile := Copy(OpenDialog1.Filename,1,P-1);
  297.     Define := True;
  298.     Button := IDNO;
  299.     with Table2 do begin
  300.       Active := False;
  301.       Databasename := DBFile;
  302.       TableName := DBFile+'.DB';
  303.       TableType := ttParadox;
  304.     end;
  305.     if FileExists(DBFile+'.DB') then begin
  306.       Button := Application.MessageBox('Delete Old Table and Continue?', 'Table Exists', mb_YesNoCancel + mb_DefButton1);
  307.       Define := (Button = IDYES);
  308.     end;
  309.     if Define then
  310.       DefineFields(Table2,OpenDialog1.Filename);
  311.     if Button<>IDCANCEL then  
  312.       BatchMove1.Execute;
  313.   end;
  314. end;
  315.  
  316. end.
  317.